﻿using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Protocol;
using MQTTnet.Server;
using System;
using System.Text;
using System.Threading.Tasks;

namespace MqttServiceDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            OpenMqttServer();
        }

        static MqttServer mqttServer;  //MQTT服务端实例

        //开启MQTT服务
        public static void OpenMqttServer()
        {
            var mqttFactory = new MqttFactory();
            //var optionsBuilder = new MqttServerOptionsBuilder()
            //    .WithDefaultEndpointPort(setting.Port);
            var mqttServerOptions = mqttFactory.CreateServerOptionsBuilder().WithDefaultEndpoint().Build();
            try
            {
                //_mqttServer = mqttFactory.CreateMqttServer(optionsBuilder.Build());
                mqttServer = mqttFactory.CreateMqttServer(mqttServerOptions);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return;
            }
            mqttServer.ClientConnectedAsync += MqttServer_ClientConnectedAsync;
            mqttServer.StartedAsync += MqttServer_StartedAsync;
            mqttServer.ClientDisconnectedAsync += MqttServer_ClientDisconnectedAsync;
            mqttServer.ClientSubscribedTopicAsync += MqttServer_ClientSubscribedTopicAsync;
            mqttServer.ValidatingConnectionAsync += MqttServer_ValidatingConnectionAsync;
            mqttServer.InterceptingPublishAsync += MqttServer_InterceptingPublishAsync;

            mqttServer.StartAsync();
            Console.WriteLine("mqtt服务启动成功!");
            TestMessage();

            Console.ReadKey();
        }

        private static async Task MqttServer_InterceptingPublishAsync(InterceptingPublishEventArgs arg)
        {
            if (arg.ApplicationMessage.Topic != "ServiceToClient" && arg.ApplicationMessage.PayloadSegment.Count > 0)
            {
                Console.WriteLine($"接收消息：{arg.ClientId} {arg.ApplicationMessage.ConvertPayloadToString()}");
            }
        }

        private static async void TestMessage()
        {
            int count = 0;
            while (true)
            {
                await Task.Delay(2000);
                count++;
                string message = $"Hello World{count}";
                var message1 = new MqttApplicationMessageBuilder().WithTopic("ServiceToClient").WithPayloadSegment(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message))).Build();

                await mqttServer.InjectApplicationMessage(new InjectedMqttApplicationMessage(message1)
                {
                    SenderClientId = "DeviceTestTool"
                });
                Console.WriteLine($"发送消息：{message}");
            }
        }

        private static async Task MqttServer_ValidatingConnectionAsync(ValidatingConnectionEventArgs c)
        {
            try
            {
                var Message = string.Format("用户尝试登录:用户ID：{0}\t用户信息：{1}\t用户密码：{2}", c.ClientId, c.UserName, c.Password) + "\r\n";
                if (string.IsNullOrWhiteSpace(c.UserName))
                {
                    Message += string.Format("用户：{0}登录失败，用户信息为空", c.ClientId) + "\r\n";
                    return;
                }
                //解析用户名和密码，这个地方需要改成查找我们自己创建的用户名和密码。
                if (c.UserName == "admin" && c.Password == "ecom1234")
                {
                    Message += c.ClientId + " 登录成功" + "\r\n";
                    Console.WriteLine(Message);
                    return;
                }
                else
                {
                    c.ReasonCode = MqttConnectReasonCode.UnspecifiedError;
                    Message += "用户名密码错误登陆失败" + "\r\n";
                    Console.WriteLine(Message);
                    return;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("登录失败:" + ex.Message);
                return;
            }
        }

        private static async Task MqttServer_ClientConnectedAsync(ClientConnectedEventArgs c)
        {
            var Message = string.Format("用户登录:用户ID：{0}\t用户信息：{1}", c.ClientId, c.UserName) + "\r\n";
            Console.WriteLine(Message);
        }

        private static async Task MqttServer_ClientDisconnectedAsync(ClientDisconnectedEventArgs arg)
        {
            //客户端断开
            var Message = "用户" + arg.ClientId + "断开" + "\r\n";
            Console.WriteLine(Message);
        }

        private static async Task MqttServer_ClientSubscribedTopicAsync(ClientSubscribedTopicEventArgs context)
        {
            try
            {
                var Message = "用户" + context.ClientId + "订阅" + "\r\n";
                Console.WriteLine(Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("订阅失败:" + ex.Message);
            }
        }

        private static async Task MqttServer_StartedAsync(EventArgs arg)
        {
            Console.WriteLine("消息服务启动成功：任意键退出" + "\r\n");
        }
    }
}
